import Vapor

protocol ResponseResultFormatProtocol {
    var status: Int {get set}
    var message: String {get set}
    var result: ResultType? {get set}
    associatedtype ResultType
}

/// Controls basic CRUD operations on `Todo`s.
final class TodoController {

    func index(_ req: Request) throws -> Future<Response> {
        
        let token =   req.http.headers.firstValue(name: HTTPHeaderName.authorization)!
        //这里将会牵扯一个 一对多的wen'ti
        //先通过Token 获取到UID
        //通过UID 获取到 tokens
        return try Account.userExist(req: req, token: token).flatMap{ (account) -> EventLoopFuture<Response> in
            //abort 通过这个来集中收集错误信息
            
            guard let rAccount = account else {
                return  ErrorModel(status: 10086, message: "登录会话不存在", result: nil).encode(status: .nonAuthoritativeInformation, for: req)
            }
            
            let result =  try Todo.todos(uid: rAccount.uid!, req: req).flatMap{ (result) -> EventLoopFuture<Response> in
                let todoList = try TodoList.init(status: 1, message: "获取成功", result: result).encode(for: req)
                return todoList
            }
            return result
        }
    }
    /// Saves a decoded `Todo` to the database.
    func create(_ req: Request) throws -> Future<Response> {

        let token =   req.http.headers.firstValue(name: HTTPHeaderName.authorization)!
        //这里将会牵扯一个 一对多的wen'ti
        //先通过Token 获取到UID
        //通过UID 获取到 tokens
        return try Account.userExist(req: req, token: token).flatMap { (account) -> EventLoopFuture<Response> in
            //abort 通过这个来集中收集错误信息
            guard let rAccount = account else {
                return  ErrorModel(status: 10086, message: "登录会话不存在", result: nil).encode(status: .nonAuthoritativeInformation, for: req)
            }
            
            let decodeResult = try req.content.decode(TodoFields.self).flatMap{ (fields) -> EventLoopFuture<Response> in
                let result =  Todo(title: fields.title!, content: fields.content!, uid: rAccount.uid!).create(on: req).flatMap{ (todo) -> EventLoopFuture<Response> in
                    return try TodoCreate(status: 1, message: "添加成功", result: true).encode(for: req)
                }
                return result
                
            }
            return decodeResult
        }
   
    }
    /// Deletes a parameterized `Todo`.
    func update(_ req: Request) throws -> Future<Response> {
        //这里将会牵扯一个 一对多的wen'ti
        //先通过Token 获取到UID
        
        let decodeResult = try req.content.decode(TodoFields.self).flatMap{ (fields) -> EventLoopFuture<Response> in
            return try Todo.getTodoByID(fields.id!, req: req)
                .flatMap{
                    guard let `todo` =  $0  else {
                        return try TodoCreate(status: 0, message: "该条记录不存在,请检查ID是否正确!", result: false).encode(for: req)
                    }
                    todo.title = fields.title!
                    todo.content = fields.content!
                    todo.updateTime = "\(Int(Date().timeIntervalSince1970))"
                    return  todo.update(on: req, originalID: fields.id).flatMap {
                        print($0)
                       return  try TodoCreate(status: 1, message: "编辑成功", result: true).encode(for: req)
                    }
            }
        }
        return decodeResult
    
    }
    
    /// Deletes a parameterized `Todo`.
    func delete(_ req: Request) throws -> Future<Response> {
        
        let decodeResult = try req.content.decode(TodoFields.self).flatMap { fields -> EventLoopFuture<Response> in
            let id = fields.id
            return try Todo.getTodoByID(id!, req: req)
                .flatMap { todo -> EventLoopFuture<Response> in
                    
                    guard let `todo` =  todo  else {
                        return try TodoCreate(status: 0, message: "该条记录不存在,请检查ID是否正确!", result: false).encode(for: req)
                    }
                    return todo.delete(on: req).flatMap {
                        print($0)
                       return try TodoCreate(status: 1, message: "删除成功", result: true).encode(for: req)
                    }
            }
        }
        return decodeResult
    }
    
}

struct TodoFields: Content {
    
    var id: Int?
    var title: String?
    var content: String?
}

/// Allows `Todo` to be used as a dynamic parameter in route definitions.
extension TodoFields: Parameter {
    static func resolveParameter(_ parameter: String, on container: Container) throws -> String {
        
        print(parameter)
        return parameter
    }
    
    typealias ResolvedParameter = String
}

struct TodoCreate: Content,ResponseResultFormatProtocol {
    typealias ResultType = Bool
    var status: Int
    var message: String
    var result: Bool?
}

struct TodoList: Content,ResponseResultFormatProtocol {
    typealias ResultType = [Todo]
    var status: Int
    var message: String
    var result: [Todo]?
}
